/*
 * Copyright (c) 2023 Cshoo Org. All Rights Reserved.
 */

package org.cshoo.tattoo.datacenter.domain.service;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.IteratorUtils;
import org.cshoo.tattoo.datacenter.domain.bo.LookupBo;
import org.cshoo.tattoo.datacenter.domain.po.Lookup;
import org.cshoo.tattoo.datacenter.domain.po.LookupItem;
import org.cshoo.tattoo.datacenter.domain.repository.ILookupItemRepository;
import org.cshoo.tattoo.datacenter.domain.repository.ILookupRepository;
import org.cshoo.tattoo.embed.infra.entity.PageQueryEntity;
import org.cshoo.tattoo.embed.infra.exception.NotConfiguredException;
import org.cshoo.tattoo.embed.infra.utils.AuditFieldsUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @author 杨翼
 * @since 1.0
 */
@Service
@Slf4j
public class LookupService {

    @Resource
    private ILookupRepository lookupRepository;

    @Resource
    private ILookupItemRepository lookupItemRepository;

    /**
     * 判断此编号是否存在
     *
     * @param code lookup编号
     * @return 判断结果
     */
    public boolean checkLookupCodeExists(String code) {
        Lookup lookup = lookupRepository.findByCode(code);
        log.info("lookup:{}", lookup);
        return !Objects.isNull(lookup);
    }

    /**
     * 添加一个lookup
     *
     * @param lookup lookup
     */
    public void addLookup(Lookup lookup) {
        lookup.setStatus(0);
        AuditFieldsUtils.setAddAuditFields(lookup);
        lookupRepository.save(lookup);
    }

    /**
     * 修改一个lookup
     *
     * @param updateLookup 修改lookup信息对象
     */
    public void updateLookup(Lookup updateLookup) {
        log.info("updateLookup:{}", updateLookup);
        Optional<Lookup> lookupOptional = lookupRepository.findById(updateLookup.getId());
        if (lookupOptional.isPresent()) {
            Lookup lookup = lookupOptional.get();
            lookup.setName(updateLookup.getName());
            lookup.setDescription(updateLookup.getDescription());
            lookupRepository.save(lookup);
        }
    }

    /**
     * 删除一个lookup
     *
     * @param id id
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteLookup(Long id) {
        log.info("id:{}", id);
        lookupItemRepository.deleteByLookupId(id);
        lookupRepository.deleteById(id);
    }

    /**
     * 查询lookup列表
     *
     * @return lookup列表
     */
    @SuppressWarnings("unchecked")
    public List<Lookup> queryLookups() {
        Iterable<Lookup> lookupIterable = lookupRepository.findAll();
        return IteratorUtils.toList(lookupIterable.iterator());
    }

    /**
     * 分页查询
     *
     * @param lookupPageReq 分页查询对象
     * @return 分页查询结果
     */
    public Page<Lookup> queryLookups(PageQueryEntity<String> lookupPageReq) {
        PageRequest pageRequest = PageRequest.of(lookupPageReq.getPageNumber(), lookupPageReq.getPageSize());
        String keyword = lookupPageReq.getQuery();
        return lookupRepository.findLookup(keyword, pageRequest);
    }

    /**
     * 根据lookupId查询item
     *
     * @param lookupId lookupId
     * @return item列表
     */
    public List<LookupItem> queryLookupItems(Long lookupId) {
        log.info("lookupId:{}", lookupId);
        return lookupItemRepository.findByLookupIdOrderByOrder(lookupId);
    }

    /**
     * 查询lookup item
     *
     * @param lookupPageReq lookup 请求
     * @return lookup item
     */
    public Page<LookupItem> queryLookupItems(PageQueryEntity<Long> lookupPageReq) {
        Long lookupId = lookupPageReq.getQuery();
        PageRequest pageRequest = PageRequest.of(lookupPageReq.getPageNumber(), lookupPageReq.getPageSize());
        return lookupItemRepository.findByLookupIdOrderByOrder(lookupId, pageRequest);
    }

    /**
     * 查询单个的lookup
     *
     * @param code 编号
     * @return lookup信息
     */
    public LookupBo querySingleLookup(String code) throws Exception {
        Lookup lookup = lookupRepository.findByCode(code);
        if (Objects.isNull(lookup)) {
            throw new NotConfiguredException("The lookup with code [" + code + "] is not configured");
        }
        LookupBo lookupBo = new LookupBo();
        BeanUtils.copyProperties(lookup, lookupBo);
        List<LookupItem> lookupItems = lookupItemRepository.findByLookupIdOrderByOrder(lookup.getId());
        lookupBo.setLookupItems(lookupItems);
        return lookupBo;
    }

    /**
     * 根据code和lookupId查看是否存在lookupItem
     *
     * @param code     code
     * @param lookupId lookupId
     * @return 查看存在结果
     */
    public boolean checkLookupItemCodeExists(String code, Long lookupId) {
        log.info("code:{},lookupId:{}", code, lookupId);
        return !Objects.isNull(lookupItemRepository.findByCodeAndLookupId(code, lookupId));
    }

    /**
     * 添加一个lookup项
     *
     * @param lookupItem lookup Item
     */
    public void addLookupItem(LookupItem lookupItem) throws Exception {
        log.info("lookupItem:{}", lookupItem);
        LookupItem checkLookupItem = lookupItemRepository.findByCodeAndLookupId(lookupItem.getCode(), lookupItem.getLookupId());
        if (Objects.nonNull(checkLookupItem)) {
            throw new Exception("duplicate");
        }
        lookupItemRepository.save(lookupItem);
    }

    /**
     * 修改一个lookup项
     *
     * @param lookupItem 修改lookup item
     */
    public void updateLookupItem(LookupItem lookupItem) {
        log.info("lookupItem:{}", lookupItem);
        lookupItemRepository.updateLookupItem(lookupItem);
    }

    /**
     * 删除一个lookup项
     *
     * @param id id
     */
    public void deleteLookupItem(Long id) {
        log.info("id:{}", id);
        lookupItemRepository.deleteById(id);
    }

}
